﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Runtime.Serialization;
using System.Web;
using DuelQuizzServer.exception;

namespace DuelQuizzServer
{
    public partial class User
    {
        private static Entities context;
        private static DbSet<User> entities
        {
            get
            {
                if (User.context == null)
                {
                    User.context = new Entities();
                    User.context.Configuration.ProxyCreationEnabled = false;
                    User.context.Configuration.LazyLoadingEnabled = true;
                }
                return context.User;
            }
        }

        
        public List<User> friends = new List<User>();

        internal User(int user_id)
        {
            User user = User.find(user_id);
            if (user != null)
            {
                this.id = user.id;
                this.username = user.username;
                this.password = user.password;
                this.account_type = user.account_type;
                this.avatar = user.avatar;
                this.country = user.country;
                this.creation_date = user.creation_date;
                this.enable = user.enable;
                this.friends = user.friends;
                this.last_results = user.last_results;
                this.match_count = user.match_count;
                this.notifications = user.notifications;
                this.score = user.score;
                this.theme = user.theme;
            }        
        }

        internal static User find(int id, bool lazyloading = true)
        {
            try
            {
                User user = User.entities.SingleOrDefault(p => (p.id == id));
                if (user != null && lazyloading)
                {
                    //user.friends = Friend.getFriend(id);
                    user.notifications = Notification.getNotification(id);
                    user.last_results = Result.getResults(id);
                }

                return user;
            }
            catch (Exception e)
            {
                return null;
            }
        }

        internal static User find(string username, bool lazyloading = true)
        {
            try
            {
                User user = User.entities.SingleOrDefault(p => (p.username == username));
                if (user != null && lazyloading)
                {
                    //user.friends = Friend.getFriend(user.id);
                    user.notifications = Notification.getNotification(user.id);
                    user.last_results = Result.getResults(user.id);
                }

                return user;
            }
            catch (Exception e)
            {
                return null;
            }
        }

        internal static User login(string username, string password)
        {
            try
            {
                User tmp = entities.SingleOrDefault(p => (p.username == username && p.password == password));
                return User.find(tmp.id);
            }
            catch (Exception e)
            {
                return null;
            }

        }

        internal static void add(User u)
        {
            Entities c = new Entities();
            c.User.Add(u);
            c.SaveChanges();
        }

        internal static List<User> getLeaderboard()
        {
            return entities.OrderByDescending(p => p.score).Take(500).ToList();
        }

        public override string ToString()
        {
            return username;
        }

        public int getNbUnreadNotification()
        {
            int cpt = 0;
            foreach (Notification n in notifications)
            {
                if (!n.is_read) cpt++;
            }
            return cpt;
        }


        internal void readNotifications()
        {
            
            Notification.delete(id);
        }

        internal static void update(User u){
            context.Entry(u).State = EntityState.Modified;
            context.SaveChanges();
        }
        
    }
}